/*-----------------------------------------------------------------------
 * MediaFrame is an Open Source streaming media platform in Java 
 * which provides a fast, easy to implement and extremely small applet 
 * that enables to view your audio/video content without having 
 * to rely on external player applications or bulky plug-ins.
 *
 *-----------------------------------------------------------------------
 *
 * We changed a lot of code and added a lot of functionality.
 * This includes, but not limited to, the following changes:
 * 1. The project was renamed to MediaFrame;
 * 2. The connection speed detection procedure was added;
 * 3. The JavaScript API functions were added;
 * 4. The pre and post image support functionality was added;
 * 5. The ability to save movie into the local disk was added;
 * 6. The inner buffer for a movie file was added;
 * 7. The click-through functionality was added;    
 * 8. The .zip files support was added;    
 * 9. The realtime feedback agent functionality was added.    
 * For the full list of the current functionality please visit 
 * the following web page: http://mediaframe.org/
 *    
 * 06 Jul 2002 - 19 Dec 2004 Konstantin Belous, Oleg Lebedev
 *
 *-----------------------------------------------------------------------
 *
 * I added the 'audio-chooser' which determines which audio is to
 * used.
 * 
 * -- Ron -- (29-04-2002) r_breukelaar@hotmail.com
 *
/*-----------------------------------------------------------------------
 * 29/01/00		Initial version. mdm@techie.com
/*-----------------------------------------------------------------------
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *----------------------------------------------------------------------
 */

package mediaframe.mpeg1.audio.player;

import mediaframe.mpeg1.audio.decoder.JavaLayerException;

/**
 * The <code>AudioDeviceFactory</code> class stores the factories
 * for all the audio device implementations available in the system. 
 * <p>
 * Instances of this class are thread-safe. 
 * 
 * @since 0.0.8
 * @author Mat McGowan
 */

public class AudioDeviceFactory
{

	/** The JavaSound Audio Device type. */	
	public static final int JAVA_SOUND = 0;
	/** The Eight Bit Audio Device type. */	
	public static final int EIGHT_BIT  = 1;
	
	/** The type of the Audio Device. */
	private int deviceType = -1;

	/** The single instance of the Audio Device Factory. */
	static private AudioDeviceFactory instance = null;
	
	/**
	 * This method implements singelton pattern - 
	 * creates (during the first call) and returns the single instance of <code>AudioDeviceFactory</code>.
	 * Detects (during the first call) the type of the Audio Device that could be used under the current JRE.
	 * @return the instance of the Audio Device Factory.
	 */
	static synchronized public AudioDeviceFactory loadDriverClass()
	{
		if (instance==null)
		{
			instance = new AudioDeviceFactory();
			try
			{
				instance.getClass().getClassLoader().loadClass("javax.sound.sampled.AudioInputStream");
				
				instance.deviceType = JAVA_SOUND;
			
				System.out.println("Using javax.sound.sampled for audio...");

			}
			catch(Exception e)
			{
				try
				{
					instance.getClass().getClassLoader().loadClass("sun.audio.AudioPlayer");

					instance.deviceType = EIGHT_BIT;

					System.out.println("Using sun.audio for audio...");
				}
				catch(Exception e2)
				{
				}
			}
		}
		return instance;
	}

	
	/**
	 * Creates and returns the implementation of the <code>AudioDevice</code> interface of a type that 
	 * specified by the deviceType field. 
	 * @return the implementation of the <code>AudioDevice</code> interface.
	 * @throws JavaLayerException if the implementation of the <code>AudioDevice</code> 
	 *         interface could not be created.
	 */
	public AudioDevice createAudioDevice() throws JavaLayerException {

		AudioDevice device = null;
		
		Throwable lastEx = null;

		if(deviceType != -1) {
			try {

				if(deviceType == JAVA_SOUND) 			
					device = new JavaSoundAudioDevice();
				else
					device = new EightBitAudioDevice();
			
			}
			catch (Exception ex)
			{
				lastEx = ex;
			}
			catch (LinkageError ex)
			{
				lastEx = ex;
			}
		}

		if (device==null && lastEx!=null) {
			throw new JavaLayerException("Cannot create AudioDevice "+lastEx, lastEx);
		}
		
		return device;
	}
}
